//
//  JSTimer.m
//  JSTimer
//
//  Created by JasonLee on 2020/3/3.
//  Copyright © 2020 JasonLee. All rights reserved.
//

#import "JSTimer.h"
@interface JSTimer()
@property(nonatomic,strong)dispatch_source_t timer;
@property(nonatomic,assign)BOOL resumed;
@end
@implementation JSTimer
+(JSTimer *)scheduleTimerWithInterval:(NSTimeInterval)interval
                               repeat:(BOOL)repeat
                               target:(id)target
                             selector:(SEL)selector{
    JSTimer *timer = [[self alloc] initWithTimerInterval:interval
                                        repeat:repeat
                                        target:target
                                      selector:selector
                                         block:NULL];
    dispatch_resume(timer.timer);
    timer.resumed = true;
    return timer;
}
+(JSTimer *)scheduleTimerWithInterval:(NSTimeInterval)interval
                               repeat:(BOOL)repeat
                                block:(JSTimerBlock)block{
    JSTimer *timer = [[self alloc] initWithTimerInterval:interval
                                        repeat:repeat
                                        target:nil
                                      selector:nil
                                         block:block];
    dispatch_resume(timer.timer);
    timer.resumed = true;
    return timer;
}
+(JSTimer *)timerWithInterval:(NSTimeInterval)interval
                       repeat:(BOOL)repeat
                       target:(id)target
                     selector:(SEL)selector{
    return [[self alloc] initWithTimerInterval:interval
                                        repeat:repeat
                                        target:target
                                      selector:selector
                                         block:nil];
}
+(JSTimer *)timerWithInterval:(NSTimeInterval)interval
                       repeat:(BOOL)repeat
                        block:(JSTimerBlock)block{
    return [[self alloc] initWithTimerInterval:interval
                                        repeat:repeat
                                        target:nil
                                      selector:nil
                                         block:block];
}
-(instancetype)initWithTimerInterval:(NSTimeInterval )interval
                              repeat:(BOOL)repeat
                              target:(id __nullable)target
                            selector:(SEL __nullable)selector
                               block:(JSTimerBlock)block{
    if (self = [super init]) {
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
        dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, interval * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
        dispatch_source_set_event_handler(self.timer, ^{
            [self timerActionWithTarget:target selector:selector block:block];
            if (!repeat){
                dispatch_source_cancel(self.timer);
            }
        });
    }
    return self;
}
-(void)timerActionWithTarget:(id)target
                    selector:(SEL)selector
                       block:(JSTimerBlock)block{
    if (block) {
        block();
    }
    if ([target respondsToSelector:selector]) {
        [target performSelector:selector onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
    }
}
-(void)fire{
    [self resume];
}
-(void)resume{
    if (self.timer && !self.resumed) {
        dispatch_resume(self.timer);
    }
}
-(void)pause{
    if (self.timer) {
        dispatch_suspend(self.timer);
    }
}
-(void)invalidate{
    if (self.timer) {
        dispatch_source_cancel(_timer);
        _timer = nil;
    }
}
@end
